package com.suke.czx.modules.sys.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.suke.czx.common.annotation.SysLog;
import com.suke.czx.common.base.AbstractController;
import com.suke.czx.common.utils.*;
import com.suke.czx.common.validate.EnumValue;
import com.suke.czx.common.validate.SysUserSaveGroup;
import com.suke.czx.common.validate.SysUserUpdateGroup;
import com.suke.czx.modules.sys.entity.SysUser;
import com.suke.czx.modules.sys.entity.SysUserRole;
import com.suke.czx.modules.sys.service.SysUserRoleService;
import com.suke.czx.modules.sys.service.SysUserService;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 应用模块名称: 系统用户
 * 代码描述: 系统用户控制层
 * copyright: AUZAR ALL RIGHTS RESERVED
 * company: AUZAR
 *
 * @author: 颜米晨
 * @date: 2021/08/27 16:31
 */
@Validated
@RestController
@RequestMapping("/api/user")
@AllArgsConstructor
@Api(value = "SysUserController", tags = "系统用户")
public class SysUserController extends AbstractController {

	private final SysUserService sysUserService;

	private final SysUserRoleService sysUserRoleService;

	private final PasswordEncoder passwordEncoder;

	/**
	 * 分页查询用户列表
	 * @param params 查询参数
	 * @return VO
	 */
	@RequestMapping(value = "/list", method = RequestMethod.POST)
	@PreAuthorize("hasRole('but:user:list')")
	public R list(@RequestParam Map<String, Object> params) {
		if (StrUtil.isBlankIfStr(params.get(FieldConstant.PAGE)) || StrUtil.isBlankIfStr(FieldConstant.LIMIT)) {
			return R.error("缺少分页信息");
		}
		// 查询列表数据
		QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
		// 排除管理员
		queryWrapper.ne(StrUtil.toUnderlineCase(FieldConstant.USER_ID), Constant.SUPER_ADMIN);
		if (params.size() > 2){
			queryWrapper.between(!StrUtil.isBlankIfStr(params.get(FieldConstant.ENRTY_BEGIN_DATE)) &&
					!StrUtil.isBlankIfStr(params.get(FieldConstant.ENTRY_END_DATE)), StrUtil.toUnderlineCase(FieldConstant.ENTRY_DATE),
					params.get(FieldConstant.ENRTY_BEGIN_DATE), params.get(FieldConstant.ENTRY_END_DATE))
					.like(!StrUtil.isBlankIfStr(params.get(FieldConstant.NAME)), FieldConstant.NAME, params.get(FieldConstant.NAME))
					.like(!StrUtil.isBlankIfStr(params.get(FieldConstant.DEPARTMENT)), FieldConstant.DEPARTMENT, params.get(FieldConstant.DEPARTMENT))
					.like(!StrUtil.isBlankIfStr(params.get(FieldConstant.JOBS)), FieldConstant.JOBS, params.get(FieldConstant.JOBS))
					.eq(!StrUtil.isBlankIfStr(params.get(FieldConstant.STATUS)), FieldConstant.STATUS, params.get(FieldConstant.STATUS));
		}
		IPage<SysUser> sysUserPage = sysUserService.page(mpPageConvert.pageParamConvert(params), queryWrapper);
		return Objects.requireNonNull(R.ok().put(FieldConstant.TOTAL, sysUserPage.getTotal())).setData(Optional.ofNullable(sysUserPage.getRecords()).orElse(Lists.newArrayList()));
	}

	/**
	 * 查询所有用户
	 * @return VO
	 */
	@RequestMapping(value = "/select", method = RequestMethod.POST)
	@PreAuthorize("hasRole('but:user:select')")
	public R select() {
		// 查询列表数据
		QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
		// 排除管理员
		queryWrapper.ne(StrUtil.toUnderlineCase(FieldConstant.USER_ID), Constant.SUPER_ADMIN);
		queryWrapper.eq(FieldConstant.STATUS, CodeConstant.STATUS_NORMAL);
		List<SysUser> sysUserList = sysUserService.list(queryWrapper);
		return R.ok().setData(Optional.ofNullable(sysUserList).orElse(Lists.newArrayList()));
	}

	/**
	 * 获取登录的用户信息
	 * @return VO
	 */
	@RequestMapping(value = "/info", method = RequestMethod.POST)
	public R info() {
		return R.ok().put("user", getUser());
	}

	/**
	 * 获取用户详情
	 * @param userId 用户id
	 * @return VO
	 */
	@RequestMapping(value = "/information/{userId}", method = RequestMethod.GET)
	@PreAuthorize("hasRole('but:user:info')")
	public R info(@PathVariable("userId") Long userId) {
		SysUser user = sysUserService.getById(userId);
		// 获取用户所属的角色列表
		List<Long> roleIdList = sysUserRoleService.list(new QueryWrapper<SysUserRole>().lambda()
				.eq(SysUserRole::getUserId, userId)).stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
		user.setRoleIdList(roleIdList);
		return R.ok().setData(user);
	}

	/**
	 * 保存用户
	 * @param user 用户
	 * @param bindingResult bindingResult
	 * @return VO
	 */
	@SysLog("保存用户")
	@RequestMapping(value = "/save", method = RequestMethod.POST)
	@PreAuthorize("hasRole('but:user:save')")
	public R save(@Validated(SysUserSaveGroup.class) SysUser user, BindingResult bindingResult) {
		// 入参校验结果
		if (bindingResult.hasErrors()) {
			return R.error(ParamValidateUtil.paramVilated(bindingResult));
		}
		// 校验用户名是否存在
		QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq(FieldConstant.USER_NAME, user.getUsername());
		if (ListUtil.size(sysUserService.list(queryWrapper)) != 0) {
			return R.error("用户名已存在");
		}
		user.setCreator(getUserId());
		return sysUserService.saveUser(user);
	}

	/**
	 * 更新用户
	 * @param user 用户
	 * @param bindingResult bindingResult
	 * @return VO
	 */
	@SysLog("更新用户")
	@RequestMapping(value = "/update", method = RequestMethod.POST)
	@PreAuthorize("hasRole('but:user:update')")
	public R update(@Validated(SysUserUpdateGroup.class) SysUser user, BindingResult bindingResult) {
		// 入参校验结果
		if (bindingResult.hasErrors()) {
			return R.error(ParamValidateUtil.paramVilated(bindingResult));
		}
		user.setUpdater(getUserId());
		user.setUpdateTime(new Date());
		return sysUserService.updateUser(user);
	}

	/**
	 * 修改用户密码
	 * @param password 旧密码
	 * @param newPassword 新密码
	 * @return VO
	 */
	@SysLog("修改用户密码")
	@RequestMapping(value = "/password", method = RequestMethod.POST)
	public R password(@NotBlank String password, @NotBlank String newPassword){
		newPassword = passwordEncoder.encode(newPassword);
		SysUser user = sysUserService.getById(getUserId());
		if (!passwordEncoder.matches(password, user.getPassword())) {
			return R.error("原密码不正确");
		}
		// 更新密码
		return sysUserService.updateUserPassword(getUserId(), newPassword);
	}

	/**
	 * 重置用户密码
	 * @param userId 用户编码
	 * @param password 密码
	 * @return VO
	 */
	@SysLog("重置用户密码")
	@RequestMapping(value = "/resetPassword", method = RequestMethod.POST)
	public R resetPassword(@NotNull Long userId, @NotBlank String password){
		password = passwordEncoder.encode(password);
		// 重置密码
		return sysUserService.updateUserPassword(userId, password);
	}

	/**
	 * 更新用户状态
	 * @param userId 用户编码
	 * @param status 用户状态
	 * @return VO
	 */
	@SysLog("更新用户状态")
	@RequestMapping(value = "/status", method = RequestMethod.POST)
	@PreAuthorize("hasRole('but:user:status')")
	public R status(@NotNull(message = "用户编码不能为空") Long userId,
					@NotNull(message = "用户状态不能为空") @EnumValue(intValues = {0, 1}, message = "用户状态只能是0,1") Integer status) {
		if (userId == 1L) {
			return R.error("系统管理员状态不能变更");
		}
		return sysUserService.updateUserStatus(userId, status, getUserId());
	}

}
